// Copyright (C) joyinter
// All rights reserved.
// 
// Author : Jiang Li
// Date   : 2004-8-20

#include "stdafx.h"
#include ".\bitmapdata.h"


//##ModelId=44CF17B9033C
CJoyBitmapData::CJoyBitmapData(void)
{
    m_hBitmap   = NULL;
    m_pStorage  = NULL;

    HRESULT hr;
	CComPtr<ILockBytes> lpLockBytes = NULL;
	hr = ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes);
	if (hr != S_OK)
		AfxThrowOleException(hr);
	ASSERT(lpLockBytes != NULL);
	
	hr = ::StgCreateDocfileOnILockBytes(lpLockBytes,
		STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &m_pStorage);
	if (hr != S_OK)
	{
		AfxThrowOleException(hr);
	}
	ASSERT(m_pStorage != NULL);
}

//##ModelId=44CF17B9033E
CJoyBitmapData::~CJoyBitmapData(void)
{
    if(m_pStorage != NULL)
    {
        m_pStorage->Release();
    }
}

//##ModelId=44CF17B90341
void CJoyBitmapData::SetBitmap(Bitmap* bmp)
{
    bmp->GetHBITMAP(Color(0x00000000), &m_hBitmap);
}
//##ModelId=44CF17B9034B
bool CJoyBitmapData::InsertTo(IRichEditOle* pRichEditOle,int nUser)
{
    CComPtr<IOleClientSite> pClientSite;
	pRichEditOle->GetClientSite(&pClientSite);

    HRESULT hr;

	FORMATETC fm;
	fm.cfFormat = CF_BITMAP;				// Clipboard format = CF_BITMAP
	fm.ptd = NULL;							// Target Device = Screen
	fm.dwAspect = DVASPECT_CONTENT;			// Level of detail = Full content
	fm.lindex = -1;							// Index = Not applicaple
	fm.tymed = TYMED_GDI;					// Storage medium = HBITMAP handle
	CComPtr<IOleObject> pOleObject;
	hr = ::OleCreateStaticFromData(this, IID_IOleObject,
        OLERENDER_FORMAT, &fm, pClientSite, m_pStorage, (void **)&pOleObject);
	if (hr != S_OK)
    {
        return false;
		//AfxThrowOleException(hr);
    }

	REOBJECT reobject;
	ZeroMemory(&reobject, sizeof(REOBJECT));
	reobject.cbStruct = sizeof(REOBJECT);

	CLSID clsid;
	hr = pOleObject->GetUserClassID(&clsid);
	if (hr != S_OK)
		AfxThrowOleException(hr);

	reobject.clsid = clsid;
	reobject.cp = REO_CP_SELECTION;
	reobject.dvaspect = DVASPECT_CONTENT;
	reobject.poleobj = pOleObject;
	reobject.polesite = pClientSite;
	reobject.pstg = m_pStorage;
	reobject.dwUser = nUser;

	// Insert the bitmap at the current location in the richedit control
	//
	pRichEditOle->InsertObject(&reobject);

    return true;
}
//##ModelId=44CF17B90343
bool CJoyBitmapData::InsertTo(IRichEditOle* pRichEditOle)
{
    CComPtr<IOleClientSite> pClientSite;
	pRichEditOle->GetClientSite(&pClientSite);

    HRESULT hr;

	FORMATETC fm;
	fm.cfFormat = CF_BITMAP;				// Clipboard format = CF_BITMAP
	fm.ptd = NULL;							// Target Device = Screen
	fm.dwAspect = DVASPECT_CONTENT;			// Level of detail = Full content
	fm.lindex = -1;							// Index = Not applicaple
	fm.tymed = TYMED_GDI;					// Storage medium = HBITMAP handle
	CComPtr<IOleObject> pOleObject;
	hr = ::OleCreateStaticFromData(this, IID_IOleObject,
        OLERENDER_FORMAT, &fm, pClientSite, m_pStorage, (void **)&pOleObject);
	if (hr != S_OK)
    {
        return false;
		//AfxThrowOleException(hr);
    }

	REOBJECT reobject;
	ZeroMemory(&reobject, sizeof(REOBJECT));
	reobject.cbStruct = sizeof(REOBJECT);

	CLSID clsid;
	hr = pOleObject->GetUserClassID(&clsid);
	if (hr != S_OK)
		AfxThrowOleException(hr);

	reobject.clsid = clsid;
	reobject.cp = REO_CP_SELECTION;
	reobject.dvaspect = DVASPECT_CONTENT;
	reobject.poleobj = pOleObject;
	reobject.polesite = pClientSite;
	reobject.pstg = m_pStorage;

	// Insert the bitmap at the current location in the richedit control
	//
	pRichEditOle->InsertObject(&reobject);

    return true;
}

//##ModelId=44CF17B9034E
HRESULT STDMETHODCALLTYPE CJoyBitmapData::GetData( 
    FORMATETC *pformatetcIn,        // [unique][in]
    STGMEDIUM *pmedium              // [out]
    )
{
    UNUSED_ALWAYS(pformatetcIn);

    pmedium->tymed          = TYMED_GDI;
    pmedium->hBitmap        = m_hBitmap;
    pmedium->pUnkForRelease = this;
    AddRef();
    return S_OK;
}

//##ModelId=44CF17B90352
HRESULT STDMETHODCALLTYPE CJoyBitmapData::GetDataHere( 
    FORMATETC *pformatetc,          // [unique][in]
    STGMEDIUM *pmedium              // [out][in]
    )
{
    UNUSED_ALWAYS(pformatetc);
    UNUSED_ALWAYS(pmedium);
    return E_NOTIMPL;
}

//##ModelId=44CF17B9035C
HRESULT STDMETHODCALLTYPE CJoyBitmapData::QueryGetData( 
    FORMATETC *pformatetc           // [unique][in]
    )
{
    UNUSED_ALWAYS(pformatetc);
    return E_NOTIMPL;
}

//##ModelId=44CF17B9035F
HRESULT STDMETHODCALLTYPE CJoyBitmapData::GetCanonicalFormatEtc( 
    FORMATETC *pformatectIn,        // [unique][in]
    FORMATETC *pformatetcOut        // [out]
    )
{
    UNUSED_ALWAYS(pformatectIn);
    UNUSED_ALWAYS(pformatetcOut);
    return E_NOTIMPL;
}

//##ModelId=44CF17B90363
HRESULT STDMETHODCALLTYPE CJoyBitmapData::SetData( 
    FORMATETC *pformatetc,          // [unique][in]
    STGMEDIUM *pmedium,             // [unique][in]
    BOOL fRelease                   // [in]
    )
{
    UNUSED_ALWAYS(pformatetc);
    UNUSED_ALWAYS(pmedium);
    UNUSED_ALWAYS(fRelease);
    return E_NOTIMPL;
}

//##ModelId=44CF17B9036E
HRESULT STDMETHODCALLTYPE CJoyBitmapData::EnumFormatEtc( 
    DWORD dwDirection,              // [in]
    IEnumFORMATETC **ppenumFormatEtc// [out]
    )
{
    UNUSED_ALWAYS(dwDirection);
    UNUSED_ALWAYS(ppenumFormatEtc);
    return E_NOTIMPL;
}

//##ModelId=44CF17B90372
HRESULT STDMETHODCALLTYPE CJoyBitmapData::DAdvise( 
    FORMATETC *pformatetc,          // [in]
    DWORD advf,                     // [in]
    IAdviseSink *pAdvSink,          // [unique][in]
    DWORD *pdwConnection            // [out]
    )
{
    UNUSED_ALWAYS(pformatetc);
    UNUSED_ALWAYS(advf);
    UNUSED_ALWAYS(pAdvSink);
    UNUSED_ALWAYS(pdwConnection);
    return E_NOTIMPL;
}

//##ModelId=44CF17B9037C
HRESULT STDMETHODCALLTYPE CJoyBitmapData::DUnadvise( 
    DWORD dwConnection              // [in]
    )
{
    UNUSED_ALWAYS(dwConnection);
    return E_NOTIMPL;
}

//##ModelId=44CF17B9037F
HRESULT STDMETHODCALLTYPE CJoyBitmapData::EnumDAdvise(
    IEnumSTATDATA **ppenumAdvise    // [out]
    )
{
    UNUSED_ALWAYS(ppenumAdvise);
    return E_NOTIMPL;
}

